package com.dynabook.ems.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dynabook.ems.common.BaseResponse;
import com.dynabook.ems.common.ErrorCode;
import com.dynabook.ems.common.ResultUtils;
import com.dynabook.ems.exception.BusinessException;
import com.dynabook.ems.mapper.EmsBomMapper;
import com.dynabook.ems.model.dto.*;
import com.dynabook.ems.model.entity.*;
import com.dynabook.ems.model.enums.DetailStatusEnum;
import com.dynabook.ems.model.enums.RedisKeyEnum;
import com.dynabook.ems.model.vo.*;
import com.dynabook.ems.service.*;
import com.dynabook.ems.utils.FastExcelUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
* @author tester
* @description 针对表【ems_bom】的数据库操作Service实现
* @createDate 2025-07-21 15:20:05
*/
@Service
@Slf4j
public class EmsBomServiceImpl extends ServiceImpl<EmsBomMapper, EmsBom> implements EmsBomService {
    
    @Resource
    private EmsBomDetailService bomDetailService;
    
    @Resource
    private EmsBomContactService bomContactService;


    @Resource
    private EmsWorkOrderDetailService emsWorkOrderDetailService;
    @Resource
    private EmsBomContactService emsBomContactService;
    
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private EmsEngineWorkOrderService emsEngineWorkOrderService;

    /**
     * 添加BOM
     * 
     * @param bomAddRequest BOM添加请求
     * @return 操作结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse<HashMap<String, Boolean>> addBom(BomAddRequest bomAddRequest, HttpServletRequest request) {
        if (bomAddRequest == null) {
            return ResultUtils.error(ErrorCode.PARAMS_ERROR, "请求参数为空");
        }
        
        // 从Session获取用户信息
        UserLoginVO userLoginVO = (UserLoginVO) request.getSession().getAttribute("user_login");
        if (userLoginVO == null) {
            return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "用户未登录");
        }
        
        // 获取用户信息
        String userNum = userLoginVO.getUserNum();
        String userName = userLoginVO.getUserName();
        
        if (StringUtils.isAnyBlank(userNum, userName)) {
            return ResultUtils.error(ErrorCode.PARAMS_ERROR, "用户信息不完整");
        }



        // 参数校验
        String bomNum = bomAddRequest.getBomNum();
        String productNamePrefix = bomAddRequest.getProductNamePrefix();
        String productNameSuffix = bomAddRequest.getProductNameSuffix();
        String machineName = bomAddRequest.getMachineName();
        String version = bomAddRequest.getVersion();
        String finishProductName = bomAddRequest.getFinishProductName();
        LambdaQueryWrapper<EmsBom> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EmsBom::getFinishedProductModel, productNamePrefix+"-"+productNameSuffix);
        List<EmsBom> emsBoms = this.baseMapper.selectList(queryWrapper);
        if(CollUtil.isNotEmpty(emsBoms)){
            return ResultUtils.error(ErrorCode.PARAMS_ERROR, "成品型号已存在");
        }
        List<BomAddRequest.BomDetailItem> bomDetails = bomAddRequest.getBomDetails();
        
        if (StringUtils.isAnyBlank(bomNum, machineName)) {
            return ResultUtils.error(ErrorCode.PARAMS_ERROR, "BOM编号或机型名称不能为空");
        }
        
        if (bomDetails == null || bomDetails.isEmpty()) {
            return ResultUtils.error(ErrorCode.PARAMS_ERROR, "BOM明细不能为空");
        }
        
        // 校验BOM信息中不能同时出现两个及以上的PNO或者A5A开头的modelType
        validateModelTypes(bomDetails);
        
        // 1. 保存BOM基本信息
        EmsBom emsBom = new EmsBom();
        emsBom.setBomNum(bomNum);
        emsBom.setProductNamePrefix(productNamePrefix);
        emsBom.setProductNameSuffix(productNameSuffix);
        emsBom.setFinishedProductModel(productNamePrefix+"-"+productNameSuffix);
        emsBom.setFinishProductName(finishProductName);
        emsBom.setMachineName(machineName);
        emsBom.setVersion(version);
        emsBom.setIsNewVersion(0);
        emsBom.setUserId(userNum);
        emsBom.setUserName(userName);
        emsBom.setInsertTime(LocalDateTime.now());
        emsBom.setUpdateTime(LocalDateTime.now());
        
        boolean saveResult = this.save(emsBom);
        if (!saveResult) {
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "保存BOM基本信息失败");
        }
        
        // 2. 保存BOM详细信息
        List<EmsBomDetail> bomDetailList = new ArrayList<>();
        for (BomAddRequest.BomDetailItem item : bomDetails) {
            EmsBomDetail detail = new EmsBomDetail();
            detail.setModelType(item.getModelType());
            detail.setModelName(item.getModelName());
            detail.setModelNumber(item.getModelNumber());
            detail.setModelUnit(item.getModelUnit());
            detail.setModelCategory(item.getModelCategory());
            detail.setIsFirst(item.getIsFirst());
            boolean isModification = StrUtil.equals(item.getModelCategory(), "D");
            if(isModification) {
              detail.setDetailStatus(DetailStatusEnum.MODIFICATION.getValue());
            }
            detail.setRemark(item.getRemark());
            bomDetailList.add(detail);
        }
        
        boolean saveBatchResult = bomDetailService.saveBatch(bomDetailList);
        if (!saveBatchResult) {
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "保存BOM详细信息失败");
        }
        
        // 3. 保存关联关系
        List<EmsBomContact> contactList = new ArrayList<>();
        for (EmsBomDetail detail : bomDetailList) {
            EmsBomContact contact = new EmsBomContact();
            contact.setBomId(emsBom.getId());
            contact.setBomDetailId((Long) detail.getId());
            contactList.add(contact);
        }
        
        boolean saveBatchContactResult = bomContactService.saveBatch(contactList);
        if (!saveBatchContactResult) {
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "保存BOM关联关系失败");
        }
        HashMap<String, Boolean> map = new HashMap<>();
        map.put("flag", true);
        return ResultUtils.success(map);
    }

    /**
     * 校验BOM信息中不能同时出现两个及以上的PNO或者A5A开头的modelType
     * 但可以同时存在一个PNO开头和一个A5A开头的modelType
     * 
     * @param bomDetails BOM详细信息列表
     */
    private void validateModelTypes(List<BomAddRequest.BomDetailItem> bomDetails) {
        Pattern pnoPattern = Pattern.compile("^(?i)(P).*$");
        Pattern a5aPattern = Pattern.compile("^(?i)(A).*$");
        int pnoCount = 0;
        int a5aCount = 0;
        
        // 分别统计以PNO和A5A开头的modelType数量
        for (BomAddRequest.BomDetailItem item : bomDetails) {
            String modelType = item.getModelType();
            if (modelType != null) {
                if (pnoPattern.matcher(modelType).matches()) {
                    pnoCount++;
                    if (pnoCount > 1) {
                        throw new BusinessException(ErrorCode.PARAMS_ERROR, "BOM信息中不能同时出现两个及以上以PNO开头的样品型号");
                    }
                }
                if (a5aPattern.matcher(modelType).matches()) {
                    a5aCount++;
                    if (a5aCount > 1) {
                        throw new BusinessException(ErrorCode.PARAMS_ERROR, "BOM信息中不能同时出现两个及以上以A5A开头的样品型号");
                    }
                }
            }
        }
    }

    @Override
    public String generateBomId() {
        return this.baseMapper.getBOMID();
    }

    @Override
    public Page<BomListVO> getBomList(BomListRequest bomListRequest) {
        // 参数校验
        if (bomListRequest == null) {
            bomListRequest = new BomListRequest();
        }
        
        // 设置默认排序
        if (StringUtils.isBlank(bomListRequest.getSortField())) {
            bomListRequest.setSortField("insert_time");
            bomListRequest.setSortOrder("desc");
        }
        
        // 创建分页对象
        Page<BomListVO> page = new Page<>(bomListRequest.getCurrent(), bomListRequest.getPageSize());
        
        // 执行分页查询
        return this.baseMapper.pageBomList(page, bomListRequest);
    }

    @Override
    public BaseResponse<BomDetailVO> getBomDetailById(String bomId) {
        try {
            // 查询BOM详细信息
            BomDetailVO bomDetailVO = this.baseMapper.getBomDetailById(bomId);
            List<OptionWorkOrderVO> associatedWorkOrder=this.baseMapper.getAssociatedWorkOrder(bomId);
            if (CollUtil.isNotEmpty(associatedWorkOrder)) {
                bomDetailVO.setAssociatedWorkOrder(associatedWorkOrder);
            }
            List<BomDetailVO.BomDetailItem> bomDetailItem = this.baseMapper.getBomDetail(bomId);
            bomDetailVO.setBomDetails(bomDetailItem);
            if (bomDetailVO == null) {
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "未找到对应的BOM信息");
            }
            
            // 计算是否可以编辑
            bomDetailVO.calculateCanEdit();
            
            return ResultUtils.success(bomDetailVO);
            
        } catch (Exception e) {
            log.error("查询BOM详细信息失败，bomId: {}", bomId, e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询BOM详细信息失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse<String> copyBom(BomCopyRequest bomCopyRequest, HttpServletRequest request) {
        String bomId = bomCopyRequest.getBomId();
//        String version = bomCopyRequest.getVersion();
        try {

            
            // 1. 查询原BOM信息 - 修改为使用bomNum字段查询
            EmsBom originalBom = this.getById(bomId);
            if (originalBom == null) {
                return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "原BOM不存在");
            }
//            更新老的BOM的is_new_version字段为1
            originalBom.setIsNewVersion(1);
            this.updateById(originalBom);

            // 2. 计算新版本号
            String originalVersion = originalBom.getVersion();
            String newVersion;
            if (originalVersion != null) {
                try {
                    int versionNum = Integer.parseInt(originalVersion);
                    int newVersionNum = versionNum + 1;
                    // 当版本号小于10时，前面补0
                    newVersion = String.format("%02d", newVersionNum);
                } catch (NumberFormatException e) {
                    newVersion = originalVersion + "_copy";
                }
            } else {
                newVersion = "01";
            }

            // 3. 复制BOM主表，保持BOMID不变，插入新记录
            EmsBom newBom = new EmsBom();
            newBom.setBomNum(originalBom.getBomNum()); // 保持原BOMID不变
            newBom.setProductNamePrefix(originalBom.getProductNamePrefix());
            newBom.setProductNameSuffix(originalBom.getProductNameSuffix());
            newBom.setFinishProductName(originalBom.getFinishProductName());
            newBom.setFinishedProductModel(originalBom.getFinishedProductModel());
            newBom.setMachineName(originalBom.getMachineName());
            newBom.setVersion(newVersion); // 使用新版本号
//            newBom.setAssociatedWorkOrder(originalBom.getAssociatedWorkOrder());

            // 从Session获取用户信息
            UserLoginVO userLoginVO = (UserLoginVO) request.getSession().getAttribute("user_login");
            if (userLoginVO == null) {
                return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "用户未登录");
            }
            // 获取用户信息
            String userNum = userLoginVO.getUserNum();
            String userName = userLoginVO.getUserName();
            newBom.setUserId(userNum);
            newBom.setUserName(userName);
            newBom.setIsNewVersion(0);
            newBom.setInsertTime(LocalDateTime.now());
            newBom.setUpdateTime(LocalDateTime.now());
            
            boolean bomSaveResult = this.save(newBom);
            if (!bomSaveResult) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "保存新BOM失败");
            }
            
            // 4. 查询原BOM的关联关系
            LambdaQueryWrapper<EmsBomContact> contactWrapper = new LambdaQueryWrapper<>();
            contactWrapper.eq(EmsBomContact::getBomId, bomId);
            List<EmsBomContact> originalContacts = bomContactService.list(contactWrapper);
            
            if (!originalContacts.isEmpty()) {
                // 5. 获取原BOM详情ID列表
                List<Serializable> originalDetailIds = originalContacts.stream()
                        .map(EmsBomContact::getBomDetailId)
                        .filter(Objects::nonNull)
                        .map(id -> (Serializable) id)
                        .collect(Collectors.toList());
                
                // 6. 查询原BOM详情
                List<EmsBomDetail> originalDetails = bomDetailService.listByIds(originalDetailIds);
                
                // 7. 复制BOM详情，生成新的详情ID
                List<EmsBomDetail> newDetails = new ArrayList<>();
                
                for (EmsBomDetail originalDetail : originalDetails) {
                    EmsBomDetail newDetail = new EmsBomDetail();
                    // 不设置ID，让MyBatis-Plus自动生成新的ID
                    newDetail.setModelType(originalDetail.getModelType());
                    newDetail.setModelName(originalDetail.getModelName());
                    newDetail.setModelNumber(originalDetail.getModelNumber());
                    newDetail.setModelUnit(originalDetail.getModelUnit());
                    newDetail.setModelCategory(originalDetail.getModelCategory());
                    newDetail.setRemark(originalDetail.getRemark());
                    newDetail.setIsFirst(originalDetail.getIsFirst());

                    newDetails.add(newDetail);
                }
                
                // 8. 批量保存新的BOM详情
                boolean detailSaveResult = bomDetailService.saveBatch(newDetails);
                if (!detailSaveResult) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "保存新BOM详情失败");
                }
                
                // 9. 创建新的关联关系（使用原BOMID和新的详情ID）
                List<EmsBomContact> newContacts = new ArrayList<>();
                for (EmsBomDetail newDetail : newDetails) {
                    EmsBomContact newContact = new EmsBomContact();
                    newContact.setBomId(newBom.getId()); // 使用原BOMID保持不变
                    newContact.setBomDetailId((Long) newDetail.getId()); // 使用新生成的详情ID
                    newContacts.add(newContact);
                }
                
                // 10. 批量保存新的关联关系
                boolean contactSaveResult = bomContactService.saveBatch(newContacts);
                if (!contactSaveResult) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "保存新BOM关联关系失败");
                }
            }
            
            log.info("成功复制BOM，BOMID: {}, 新版本: {}", bomId, newVersion);
            return ResultUtils.success(bomId);
            
        } catch (BusinessException e) {
            log.error("复制BOM失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            // 日志记录：BOMID 新版本 异常信息
            log.error("复制BOM时发生异常，BOMID: {},异常信息: {}", bomId, e.getMessage());
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "复制BOM失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse<Boolean> editBom(BomEditRequest bomEditRequest) {
        Long bomId = bomEditRequest.getId();
        try {

            String productNamePrefix = bomEditRequest.getProductNamePrefix();
            String productNameSuffix = bomEditRequest.getProductNameSuffix();
            String finishProductName = bomEditRequest.getFinishProductName();
            String machineName = bomEditRequest.getMachineName();
            List<BomEditRequest.BomDetailEditItem> bomDetails = bomEditRequest.getBomDetails();
            
            // 1. 验证BOM是否存在
            EmsBom existingBom = this.getById(bomId);
            if (existingBom == null) {
                return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "BOM不存在");
            }
            
            // 2. 使用条件更新BOM主表字段
            LambdaUpdateWrapper<EmsBom> updateWrapper = new LambdaUpdateWrapper<>();
             updateWrapper.eq(EmsBom::getId, bomId)
                     .set(EmsBom::getProductNamePrefix, productNamePrefix)
                     .set(EmsBom::getProductNameSuffix, productNameSuffix)
                     .set(EmsBom::getFinishedProductModel, productNamePrefix+"-"+productNameSuffix)
                     .set(EmsBom::getFinishProductName, finishProductName)
                     .set(EmsBom::getMachineName, machineName)
                     .set(EmsBom::getUpdateTime, LocalDateTime.now());;
            boolean bomUpdateResult = this.update(updateWrapper);
            if (!bomUpdateResult) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新BOM主表失败");
            }
            
            // 3. 处理BOM详情：存在则更新，不存在则插入
            List<EmsBomDetail> updateDetails = new ArrayList<>();
            List<EmsBomDetail> insertDetails = new ArrayList<>();
            List<EmsBomContact> insertContacts = new ArrayList<>(); // ✅ 修复：声明缺失的变量
            
            for (BomEditRequest.BomDetailEditItem item : bomDetails) {
                EmsBomDetail detail = new EmsBomDetail();
                detail.setModelType(item.getModelType());
                detail.setModelName(item.getModelName());
                detail.setModelNumber(item.getModelNumber());
                detail.setModelUnit(item.getModelUnit());
                detail.setModelCategory(item.getModelCategory());
                detail.setRemark(item.getRemark());
                Long detailId = item.getId();
                // 判断是新增还是更新
                if (detailId != null) {
                    // 更新操作：验证详情记录是否存在
                    EmsBomDetail existingDetail = bomDetailService.getById(detailId);
                    if (existingDetail != null) {
                        // 存在则更新
                        detail.setId(detailId);
                        updateDetails.add(detail);
                    } else {
                        detail.setId(null);
                        // 不存在则作为新增处理
                        insertDetails.add(detail);
                    }
                } else {
                    // 新增操作：不设置ID，让数据库自动生成
                    insertDetails.add(detail);
                }
            }
            
            // 执行更新操作
            if (!updateDetails.isEmpty()) {
                boolean updateResult = bomDetailService.updateBatchById(updateDetails);
                if (!updateResult) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新BOM详情失败");
                }
            }
            
            // 执行新增操作
            if (!insertDetails.isEmpty()) {
                boolean insertResult = bomDetailService.saveBatch(insertDetails);
                if (!insertResult) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "新增BOM详情失败");
                }
                
                // 为新增的详情创建关联关系
                for (EmsBomDetail newDetail : insertDetails) {
                    // 检查EmsBomContact表中是否已存在该bom_detail_id的记录
                    LambdaQueryWrapper<EmsBomContact> contactCheckWrapper = new LambdaQueryWrapper<>();
                    contactCheckWrapper.eq(EmsBomContact::getBomDetailId, newDetail.getId());
                    EmsBomContact existingContact = bomContactService.getOne(contactCheckWrapper);
                    
                    // 如果不存在，则插入新记录
                    if (existingContact == null) {
                        EmsBomContact contact = new EmsBomContact();
                        contact.setBomId(bomId);
                        contact.setBomDetailId(newDetail.getId());
                        insertContacts.add(contact);
                    }
                }
            }
            
            // 对于已存在的详情，也需要检查关联关系
            for (EmsBomDetail updateDetail : updateDetails) {
                // 检查EmsBomContact表中是否已存在该bom_detail_id的记录
                LambdaQueryWrapper<EmsBomContact> contactCheckWrapper = new LambdaQueryWrapper<>();
                contactCheckWrapper.eq(EmsBomContact::getBomDetailId, updateDetail.getId());
                EmsBomContact existingContact = bomContactService.getOne(contactCheckWrapper);
                
                // 如果不存在，则插入新记录
                if (existingContact == null) {
                    EmsBomContact contact = new EmsBomContact();
                    contact.setBomId(bomId);
                    contact.setBomDetailId(updateDetail.getId());
                    insertContacts.add(contact);
                }
            }
            
            // 如果有需要新增的关联关系，批量保存
            if (!insertContacts.isEmpty()) {
                boolean contactResult = bomContactService.saveBatch(insertContacts);
                if (!contactResult) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "保存BOM关联关系失败");
                }
            }
            
            return ResultUtils.success(true);
            
        } catch (BusinessException e) {
            log.error("编辑BOM失败，bomId: {}, 错误: {}", bomId, e.getMessage());

            throw e;
        } catch (Exception e) {
            log.error("编辑BOM失败，bomId: {}", bomId, e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "编辑BOM失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse<Boolean> deleteBomByIds(BomDeleteRequest bomDeleteRequest) {
        List<Long> bomIds = bomDeleteRequest.getBomIds();
        // 参数校验
        if (bomIds == null || bomIds.isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "BOM ID列表不能为空" );
        }
        
        try {
            // 1. 先检查所有BOM是否都存在，并检查关联工单
            for (Long bomId : bomIds) {
                EmsBom existingBom = this.getById(bomId);
                if (existingBom == null) {
                    log.warn("BOM不存在，id: {}", bomId);
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "BOM不存在" );
                }
                
                // 检查关联工单，如果不为空则不能删除
                if (existingBom.getAssociatedWorkOrder() != null && 
                    !existingBom.getAssociatedWorkOrder().trim().isEmpty()) {
                    log.warn("BOM已关联工单，不能删除，id: {}, workOrder: {}", bomId, existingBom.getAssociatedWorkOrder());
                    throw new BusinessException(ErrorCode.OPERATION_ERROR, "BOM已关联工单，不能删除");
                }
            }
            
            // 2. 批量删除所有相关数据
            for (Long bomId : bomIds) {
                EmsBom existingBom = this.getById(bomId);
                // 删除BOM关联关系和详情
                LambdaQueryWrapper<EmsBomContact> contactQueryWrapper = new LambdaQueryWrapper<>();
                contactQueryWrapper.eq(EmsBomContact::getBomId, existingBom.getId());
                List<EmsBomContact> contacts = bomContactService.list(contactQueryWrapper);
                
                if (!contacts.isEmpty()) {
                    // 获取所有关联的详情ID
                    List<Object> detailIds = contacts.stream()
                            .map(EmsBomContact::getBomDetailId)
                            .collect(Collectors.toList());
                    
                    // 删除BOM详情
                    if (!detailIds.isEmpty()) {
                        boolean detailDeleteResult = bomDetailService.removeByIds(detailIds);
                        if (!detailDeleteResult) {
                            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除BOM详情失败: " + bomId );
                        }
                    }
                    
                    // 删除关联关系
                    boolean contactDeleteResult = bomContactService.remove(contactQueryWrapper);
                    if (!contactDeleteResult) {
                        throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除BOM关联关系失败: " + bomId );
                    }
                }
                
                // 删除BOM主表记录（根据主键id）
                boolean bomDeleteResult = this.removeById(bomId);
                if (!bomDeleteResult) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除BOM主表记录失败: " + bomId);
                }
                
                log.info("成功删除BOM，id: {}", bomId);
            }
            
            log.info("批量删除BOM成功，共删除{}个", bomIds.size());
            return ResultUtils.success(true);
            
        } catch (BusinessException e) {
            log.error("批量删除BOM业务异常: {}", e.getMessage());
            throw e; // 重新抛出业务异常，触发事务回滚
        } catch (Exception e) {
            log.error("批量删除BOM系统异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "批量删除BOM失败");
        }
    }

    @Override
    public BaseResponse getBomDetailByNumAndVersion(String bomNum, String version) {
        try {
            // 查询BOM详细信息
            BomDetailVO bomDetailVO = this.baseMapper.getBomDetailByNumAndVersion(bomNum, version);
            
            if (bomDetailVO == null) {
                return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "未找到对应的BOM信息");
            }
              // 计算是否可以编辑
            bomDetailVO.calculateCanEdit();
            
            return ResultUtils.success(bomDetailVO);
            
        } catch (Exception e) {
            log.error("根据BOM编号和版本号查询BOM详细信息失败，bomNum: {}, version: {}", bomNum, version, e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询BOM详细信息失败");
        }
    }

    @Override
    public BaseResponse<List<CategoryOptions>> getVersionOptionsByBomNum(String bomNum) {
        try {
            if (StringUtils.isBlank(bomNum)) {
                return ResultUtils.error(ErrorCode.PARAMS_ERROR, "BOM编号不能为空");
            }
            
            // 查询该BOM编号下的所有版本
            List<String> versions = this.baseMapper.getVersionsByBomNum(bomNum);
            
            // 转换为CategoryOptions格式
            List<CategoryOptions> options = versions.stream()
                    .map(version -> {
                        CategoryOptions option = new CategoryOptions();
                        option.setName("Version"+version);
                        option.setValue(version);
                        return option;
                    })
                    .collect(Collectors.toList());
            
            return ResultUtils.success(options);
            
        } catch (Exception e) {
            log.error("根据BOM编号查询版本选项失败，bomNum: {}", bomNum, e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询版本选项失败");
        }
    }

    @Override
    public BaseResponse<SelectCategoryVO> getVersionOptionsByFinishedProductModel(String finishedProductModel) {
        try {
            if (StringUtils.isBlank(finishedProductModel)) {
                return ResultUtils.error(ErrorCode.PARAMS_ERROR, "成品型号不能为空");
            }
            
            // 查询该成品型号下的所有版本
            List<String> versions = this.baseMapper.getVersionsByFinishedProductModel(finishedProductModel);
            
            // 转换为CategoryOptions格式
            List<CategoryOptions> options = versions.stream()
                    .filter(version -> StringUtils.isNotBlank(version)) // 过滤空值
                    .map(version -> {
                        CategoryOptions option = new CategoryOptions();
                        option.setName("V" + version);  // name是V+version
                        option.setValue(version);       // value是原始version值
                        return option;
                    })
                    .collect(Collectors.toList());
            
            // 获取最大版本号
            String maxVersion = versions.stream()
                    .filter(version -> StringUtils.isNotBlank(version)) // 过滤空值
                    .max((v1, v2) -> {
                        try {
                            // 尝试按数字比较
                            Integer num1 = Integer.parseInt(v1);
                            Integer num2 = Integer.parseInt(v2);
                            return num1.compareTo(num2);
                        } catch (NumberFormatException e) {
                            // 如果不是数字，按字符串比较
                            return v1.compareTo(v2);
                        }
                    })
                    .orElse(""); // 如果没有版本号，返回空字符串
            
            SelectCategoryVO selectCategoryVO = new SelectCategoryVO();
            selectCategoryVO.setOptions(options);
            selectCategoryVO.setValue(maxVersion);
            return ResultUtils.success(selectCategoryVO);
        } catch (Exception e) {
            log.error("根据成品型号获取版本选项失败，成品型号: {}", finishedProductModel, e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取版本选项失败");
        }
    }

    @Override
    public BaseResponse<List<CategoryOptions>> getFinishedProductModelOptions() {
        try {
            // 查询所有去重的成品型号
            List<String> finishedProductModels = this.baseMapper.getDistinctFinishedProductModels();
            
            // 转换为CategoryOptions格式
            List<CategoryOptions> options = finishedProductModels.stream()
                    .filter(model -> StringUtils.isNotBlank(model)) // 过滤空值
                    .map(model -> {
                        CategoryOptions option = new CategoryOptions();
                        option.setName(model);
                        option.setValue(model);
                        return option;
                    })
                    .collect(Collectors.toList());
            
            return ResultUtils.success(options);
        } catch (Exception e) {
            log.error("获取成品型号选项失败", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取成品型号选项失败");
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse<CreateWorkOrderVO> getBomDetailByFinishedProductModelAndVersion(String finishedProductModel, String version,String workOrderNumber) {
        try {
            // 清理当前工单号相关的Redis缓存
            clearWorkOrderRedisCache(workOrderNumber);
//
////            // 删除当前工单号在ems_work_order_detail表中的已有数据
//            clearExistingWorkOrderDetails(workOrderNumber);
            
            // 查询BOM详细信息
            BomDetailVO bomDetailVO = this.baseMapper.getBomDetailByFinishedProductModelAndVersion(finishedProductModel, version);
    
            if (bomDetailVO == null) {
                return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "BOM详情为空,请选择其他的BOM");
            }
    
            // 创建返回对象
            CreateWorkOrderVO createWorkOrderVO = new CreateWorkOrderVO();
            
            // 设置基本信息（从BomDetailVO中获取）
            createWorkOrderVO.setProductName(bomDetailVO.getProductName());
            createWorkOrderVO.setFinishProductName(bomDetailVO.getFinishProductName());
            createWorkOrderVO.setMachineName(bomDetailVO.getMachineName());
            createWorkOrderVO.setVersion(bomDetailVO.getVersion());
            
            // 处理BomDetailItem列表
            List<CreateWorkOrderVO.BomDetailItem> resultBomDetails = new ArrayList<>();
            
            if (bomDetailVO.getBomDetails() != null && !bomDetailVO.getBomDetails().isEmpty()) {
                for (BomDetailVO.BomDetailItem sourceItem : bomDetailVO.getBomDetails()) {
                    LambdaQueryWrapper<EmsWorkOrderDetail> emsWorkOrderDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    emsWorkOrderDetailLambdaQueryWrapper.eq(EmsWorkOrderDetail::getBomDetailId, sourceItem.getId());
                    emsWorkOrderDetailLambdaQueryWrapper.eq(EmsWorkOrderDetail::getWorkOrderNumber, workOrderNumber);
                    EmsWorkOrderDetail emsWorkOrderDetail = emsWorkOrderDetailService.getOne(emsWorkOrderDetailLambdaQueryWrapper);
                    CreateWorkOrderVO.BomDetailItem resultItem = new CreateWorkOrderVO.BomDetailItem();
                    if(emsWorkOrderDetail != null){
                        resultItem.setCategory(emsWorkOrderDetail.getCategory());
                        resultItem.setId(emsWorkOrderDetail.getId().toString()); // 使用新插入记录的ID
                        resultItem.setModelType(emsWorkOrderDetail.getModelType());
                        resultItem.setModelName(emsWorkOrderDetail.getModelName());
                        resultItem.setModelNumber(emsWorkOrderDetail.getModelNumber().toString());
                        resultItem.setModelUnit(emsWorkOrderDetail.getModelUnit());
                        resultItem.setModelCategory(emsWorkOrderDetail.getModelCategory());
                        resultItem.setRemark(emsWorkOrderDetail.getRemark());
                        resultItem.setDetailStatus(DetailStatusEnum.getTextByValue(emsWorkOrderDetail.getDetailStatus()));
                        resultItem.setIsFirst(sourceItem.getIsFirst());
                    }else{
                        // 创建EmsWorkOrderDetail实体用于插入数据库
                        EmsWorkOrderDetail workOrderDetail = new EmsWorkOrderDetail();
                        workOrderDetail.setModelType(sourceItem.getModelType());
                        workOrderDetail.setModelName(sourceItem.getModelName());
                        workOrderDetail.setIsFirst(sourceItem.getIsFirst());
                        // 将String类型的modelNumber转换为Integer
                        if (StringUtils.isNotBlank(sourceItem.getModelNumber())) {
                            try {
                                workOrderDetail.setModelNumber(Integer.valueOf(sourceItem.getModelNumber()));
                            } catch (NumberFormatException e) {
                                log.warn("样品数量转换失败，使用默认值0: {}", sourceItem.getModelNumber());
                                workOrderDetail.setModelNumber(0);
                            }
                        } else {
                            workOrderDetail.setModelNumber(0);
                        }
                        if(sourceItem.getModelCategory().equals("D")){
                            workOrderDetail.setDetailStatus(DetailStatusEnum.MODIFICATION.getValue());
                            workOrderDetail.setTotalNum(Integer.valueOf(sourceItem.getModelNumber()));
                        }else{
                            workOrderDetail.setDetailStatus(DetailStatusEnum.BEFORE_SELECTED.getValue());
                        }
                        workOrderDetail.setWorkOrderNumber(workOrderNumber);
                        workOrderDetail.setModelUnit(sourceItem.getModelUnit());
                        workOrderDetail.setModelCategory(sourceItem.getModelCategory());
                        workOrderDetail.setRemark(sourceItem.getRemark());
                        workOrderDetail.setInsertTime(LocalDateTime.now());
                        workOrderDetail.setUpdateTime(LocalDateTime.now());
                        workOrderDetail.setIsDelete(0);
                        workOrderDetail.setBomDetailId(sourceItem.getId());
                        workOrderDetail.setIsFirst(sourceItem.getIsFirst());
                        // 插入到数据库
                        boolean saveResult = emsWorkOrderDetailService.save(workOrderDetail);
                        if (!saveResult) {
                            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "插入工单详情失败");
                        }
                        EmsBomContact emsBomContact = new EmsBomContact();
                        emsBomContact.setBomDetailId(workOrderDetail.getId());
                        emsBomContact.setBomId(bomDetailVO.getBomId());
                        emsBomContact.setIsBom(1);
                        emsBomContactService.save(emsBomContact);
                        // 创建返回的BomDetailItem
                        resultItem.setId(workOrderDetail.getId().toString()); // 使用新插入记录的ID
                        resultItem.setModelType(workOrderDetail.getModelType());
                        resultItem.setModelName(workOrderDetail.getModelName());
                        resultItem.setModelNumber(workOrderDetail.getModelNumber().toString());
                        resultItem.setModelUnit(workOrderDetail.getModelUnit());
                        resultItem.setModelCategory(workOrderDetail.getModelCategory());
                        resultItem.setRemark(workOrderDetail.getRemark());
                        resultItem.setDetailStatus(DetailStatusEnum.getTextByValue(workOrderDetail.getDetailStatus()));
                    }
                    resultBomDetails.add(resultItem);
                }
            }
            
            createWorkOrderVO.setBomDetails(resultBomDetails);
            
            return ResultUtils.success(createWorkOrderVO);
    
        } catch (Exception e) {
            log.error("根据成品型号和版本号查询BOM详细信息失败，成品型号: {}, 版本号: {}", finishedProductModel, version, e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询BOM详细信息失败: " + e.getMessage());
        }
    }

    @Override
    public BaseResponse<List<CategoryOptions>> getTypeOptions() {
        List<CategoryOptions> typeOptions = this.baseMapper.getTypeOptions();
        return ResultUtils.success(typeOptions);
    }

    // 导出专用线程池
    private final ThreadPoolExecutor exportThreadPool = new ThreadPoolExecutor(
            4, // 核心线程数
            8, // 最大线程数
            60L, TimeUnit.SECONDS, // 空闲线程存活时间
            new LinkedBlockingQueue<>(100), // 队列容量
            new ThreadFactory() {
                private final AtomicInteger threadNumber = new AtomicInteger(1);
                @Override
                public Thread newThread(Runnable r) {
                    Thread t = new Thread(r, "BOM-Export-Thread-" + threadNumber.getAndIncrement());
                    t.setDaemon(false);
                    return t;
                }
            },
            new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略：调用者执行
    );

    @Override
    public void exportBomData(BomExportRequest bomExportRequest, HttpServletResponse response) {
        long startTime = System.currentTimeMillis();
        try {
            log.info("开始导出BOM数据，参数: {}", bomExportRequest);
            
            // 获取导出数据
            List<Long> bomIds = null;
            if (bomExportRequest != null && bomExportRequest.getBomIds() != null && !bomExportRequest.getBomIds().isEmpty()) {
                bomIds = bomExportRequest.getBomIds();
            }
            
            // 并行查询和处理导出数据
            List<BomExportVO> exportData = exportBomDataWithMultiThreading(bomIds);
            
            // 检查并处理空数据
            if (exportData == null || exportData.isEmpty()) {
                log.warn("没有找到可导出的BOM数据");
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "没有找到可导出的数据");
            }
            
            log.info("查询和处理BOM导出数据完成，数量: {}，耗时: {}ms", 
                    exportData.size(), System.currentTimeMillis() - startTime);
            
            // 生成文件名加年月日时分秒
            String fileName = "BOM数据" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
            
            // 使用FastExcelUtils导出
            long excelStartTime = System.currentTimeMillis();
            FastExcelUtils.exportExcelWithStyle(
                exportData, 
                BomExportVO.class, 
                fileName, 
                "BOM数据", 
                response
            );
            
            long totalTime = System.currentTimeMillis() - startTime;
            long excelTime = System.currentTimeMillis() - excelStartTime;
            log.info("BOM数据导出完成，共导出 {} 条记录，总耗时: {}ms，Excel生成耗时: {}ms", 
                    exportData.size(), totalTime, excelTime);
            
        } catch (BusinessException e) {
            log.error("导出BOM数据业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("导出BOM数据失败", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "导出BOM数据失败: " + e.getMessage());
        }
    }

    /**
     * 使用多线程优化导出数据查询和处理
     * @param bomIds BOM ID列表
     * @return 处理后的导出数据
     */
    private List<BomExportVO> exportBomDataWithMultiThreading(List<Long> bomIds) {
        try {
            // 1. 先获取数据总量以决定是否需要分页
            List<BomExportVO> allData;
            
            if (bomIds == null || bomIds.isEmpty()) {
                // 查询所有数据时使用分页并行处理
                allData = getExportDataWithPaging();
            } else {
                // 指定ID时，根据数量决定处理策略
                if (bomIds.size() > 1000) {
                    // 大数据量时分批并行处理
                    allData = getExportDataByIdsWithBatching(bomIds);
                } else {
                    // 小数据量直接查询
                    allData = this.baseMapper.getExportData(bomIds);
                }
            }
            
            // 2. 并行处理数据预处理
            if (allData != null && !allData.isEmpty()) {
                allData = preprocessExportDataInParallel(allData);
            }
            
            return allData;
            
        } catch (Exception e) {
            log.error("多线程导出数据处理失败", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "数据处理失败: " + e.getMessage());
        }
    }
    
    /**
     * 分页并行查询所有导出数据
     */
    private List<BomExportVO> getExportDataWithPaging() {
        try {
            // 先查询总数
            Long totalCount = this.baseMapper.getExportDataCount(null);
            if (totalCount == null || totalCount == 0) {
                return new ArrayList<>();
            }
            
            log.info("开始分页并行查询，总数据量: {}", totalCount);
            
            // 计算分页参数
            int pageSize = 2000; // 每页2000条
            int totalPages = (int) Math.ceil((double) totalCount / pageSize);
            
            // 创建并行任务
            List<CompletableFuture<List<BomExportVO>>> futures = new ArrayList<>();
            
            for (int page = 0; page < totalPages; page++) {
                final int currentPage = page;
                final int offset = page * pageSize;
                
                CompletableFuture<List<BomExportVO>> future = CompletableFuture.supplyAsync(() -> {
                    try {
                        log.debug("查询第{}页数据，offset: {}, limit: {}", currentPage + 1, offset, pageSize);
                        return this.baseMapper.getExportDataWithPaging(null, offset, pageSize);
                    } catch (Exception e) {
                        log.error("查询第{}页数据失败", currentPage + 1, e);
                        return new ArrayList<BomExportVO>();
                    }
                }, (Executor)exportThreadPool);
                
                futures.add(future);
            }
            
            // 等待所有任务完成并合并结果
            List<BomExportVO> allResults = new ArrayList<>();
            CompletableFuture<Void> allFutures = CompletableFuture.allOf(
                futures.toArray(new CompletableFuture[0])
            );
            
            allFutures.get(30, TimeUnit.SECONDS); // 30秒超时
            
            for (CompletableFuture<List<BomExportVO>> future : futures) {
                List<BomExportVO> pageResult = future.get();
                if (pageResult != null && !pageResult.isEmpty()) {
                    allResults.addAll(pageResult);
                }
            }
            
            log.info("分页并行查询完成，实际查询到数据量: {}", allResults.size());
            return allResults;
            
        } catch (Exception e) {
            log.error("分页并行查询失败", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "分页查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 分批并行查询指定ID的导出数据
     */
    private List<BomExportVO> getExportDataByIdsWithBatching(List<Long> bomIds) {
        try {
            log.info("开始分批并行查询，ID数量: {}", bomIds.size());
            
            // 分批处理
            int batchSize = 500; // 每批500个ID
            List<List<Long>> batches = new ArrayList<>();
            
            for (int i = 0; i < bomIds.size(); i += batchSize) {
                int end = Math.min(i + batchSize, bomIds.size());
                batches.add(bomIds.subList(i, end));
            }
            
            // 创建并行任务
            List<CompletableFuture<List<BomExportVO>>> futures = new ArrayList<>();
            
            for (int i = 0; i < batches.size(); i++) {
                final List<Long> batch = batches.get(i);
                final int batchIndex = i;
                
                CompletableFuture<List<BomExportVO>> future = CompletableFuture.supplyAsync(() -> {
                    try {
                        log.debug("查询第{}批数据，ID数量: {}", batchIndex + 1, batch.size());
                        return this.baseMapper.getExportData(batch);
                    } catch (Exception e) {
                        log.error("查询第{}批数据失败", batchIndex + 1, e);
                        return new ArrayList<BomExportVO>();
                    }
                }, (Executor)exportThreadPool);
                
                futures.add(future);
            }
            
            // 等待所有任务完成并合并结果
            List<BomExportVO> allResults = new ArrayList<>();
            CompletableFuture<Void> allFutures = CompletableFuture.allOf(
                futures.toArray(new CompletableFuture[0])
            );
            
            allFutures.get(30, TimeUnit.SECONDS); // 30秒超时
            
            for (CompletableFuture<List<BomExportVO>> future : futures) {
                List<BomExportVO> batchResult = future.get();
                if (batchResult != null && !batchResult.isEmpty()) {
                    allResults.addAll(batchResult);
                }
            }
            
            log.info("分批并行查询完成，实际查询到数据量: {}", allResults.size());
            return allResults;
            
        } catch (Exception e) {
            log.error("分批并行查询失败", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "分批查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 并行处理数据预处理
     */
    private List<BomExportVO> preprocessExportDataInParallel(List<BomExportVO> exportData) {
        if (exportData == null || exportData.isEmpty()) {
            return new ArrayList<>();
        }
        
        try {
            log.info("开始并行预处理数据，数据量: {}", exportData.size());
            long startTime = System.currentTimeMillis();
            
            // 使用并行流处理数据，移除大量的debug日志以提升性能
            List<BomExportVO> processedData = exportData.parallelStream()
                .map(this::cleanBomExportVOOptimized)
                .collect(Collectors.toList());
            
            long processingTime = System.currentTimeMillis() - startTime;
            log.info("并行预处理数据完成，耗时: {}ms", processingTime);
            
            return processedData;
            
        } catch (Exception e) {
            log.error("并行数据预处理失败", e);
            // 降级到单线程处理
            log.warn("降级到单线程预处理");
            return preprocessExportData(exportData);
        }
    }
    
    /**
     * 优化的数据清理方法，减少日志输出
     */
    private BomExportVO cleanBomExportVOOptimized(BomExportVO bomExportVO) {
        if (bomExportVO == null) {
            return new BomExportVO();
        }
        
        // 处理所有可能为null的字段，但移除debug日志以提升性能
        if (bomExportVO.getBomNum() == null) {
            bomExportVO.setBomNum("");
        }
        if (bomExportVO.getProductName() == null) {
            bomExportVO.setProductName("");
        }
        if (bomExportVO.getVersion() == null) {
            bomExportVO.setVersion("");
        }
        if (bomExportVO.getFinishProductName() == null) {
            bomExportVO.setFinishProductName("");
        }
        if (bomExportVO.getMachineName() == null) {
            bomExportVO.setMachineName("");
        }
        if (bomExportVO.getModelType() == null) {
            bomExportVO.setModelType("");
        }
        if (bomExportVO.getModelName() == null) {
            bomExportVO.setModelName("");
        }
        if (bomExportVO.getModelNumber() == null) {
            bomExportVO.setModelNumber("");
        }
        if (bomExportVO.getModelUnit() == null) {
            bomExportVO.setModelUnit("");
        }
        if (bomExportVO.getModelCategory() == null) {
            bomExportVO.setModelCategory("");
        }
        if (bomExportVO.getRemark() == null) {
            bomExportVO.setRemark("");
        }
        
        return bomExportVO;
    }

    @Override
    public List<OptionVO> getExistProductName(String productNamePrefix) {
        List<OptionVO> existProductNames = this.baseMapper.getExistProductName(productNamePrefix);
        return Optional.ofNullable(existProductNames).orElse(new ArrayList<>());
    }

    @Override
    public boolean checkExistProductName(String finishedProductModel) {

        LambdaQueryWrapper<EmsBom> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EmsBom::getFinishedProductModel, finishedProductModel);
        List<EmsBom> emsBoms = this.baseMapper.selectList(queryWrapper);
        if(CollUtil.isNotEmpty(emsBoms)){
            return true;
        }
        return false;
    }

    @Override
    public BaseResponse<Boolean> beforeAdd(String workOrderNumber) {
        boolean result = clearExistingWorkOrderDetails(workOrderNumber);
        return ResultUtils.success(result);
    }

    /**
     * 预处理导出数据，防止空指针异常
     * @param exportData 原始导出数据
     * @return 处理后的导出数据
     */
    private List<BomExportVO> preprocessExportData(List<BomExportVO> exportData) {
        if (exportData == null) {
            return new ArrayList<>();
        }
        
        return exportData.stream().map(this::cleanBomExportVO).collect(Collectors.toList());
    }
    
    /**
     * 清理单个BomExportVO对象，防止null值
     * @param bomExportVO 原始对象
     * @return 清理后的对象
     */
    private BomExportVO cleanBomExportVO(BomExportVO bomExportVO) {
        if (bomExportVO == null) {
            log.warn("发现null的BomExportVO对象，创建新对象");
            bomExportVO = new BomExportVO();
        }
        
        // 记录原始数据状态
        log.debug("清理BomExportVO - bomNum: {}, productName: {}, version: {}, associatedWorkOrder: {}, userName: {}, insertTime: {}", 
                bomExportVO.getBomNum(), bomExportVO.getProductName(), bomExportVO.getVersion(), 
                bomExportVO.getInsertTime());
        
        // 处理所有可能为null的字段
        if (bomExportVO.getBomNum() == null) {
            bomExportVO.setBomNum("");
            log.debug("bomNum为null，已设置为空字符串");
        }
        if (bomExportVO.getProductName() == null) {
            bomExportVO.setProductName("");
            log.debug("productName为null，已设置为空字符串");
        }
        if (bomExportVO.getVersion() == null) {
            bomExportVO.setVersion("");
            log.debug("version为null，已设置为空字符串");
        }
//        if (bomExportVO.getAssociatedWorkOrder() == null) {
//            bomExportVO.setAssociatedWorkOrder("");
//            log.debug("associatedWorkOrder为null，已设置为空字符串");
//        }
//        if (bomExportVO.getUserName() == null) {
//            bomExportVO.setUserName("");
//            log.debug("userName为null，已设置为空字符串");
//        }
        // insertTime 如果为null，EasyExcel会处理，不需要特殊处理
        
        return bomExportVO;
    }
    
    /**
     * 清理当前工单号在ems_work_order_detail表中的已有数据
     * @param workOrderNumber 工单号
     */
    private Boolean clearExistingWorkOrderDetails(String workOrderNumber) {
        if (StringUtils.isBlank(workOrderNumber)) {
            return false;
        }
        
        try {
            // 查询当前工单号的所有工单详情
            LambdaQueryWrapper<EmsWorkOrderDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(EmsWorkOrderDetail::getWorkOrderNumber, workOrderNumber);
            List<EmsWorkOrderDetail> existingDetails = emsWorkOrderDetailService.list(queryWrapper);
            
            if (!existingDetails.isEmpty()) {
                // 删除现有的工单详情数据
                LambdaQueryWrapper<EmsEngineWorkOrder> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(EmsEngineWorkOrder::getWorkOrderNumber,workOrderNumber);
                boolean remove = emsEngineWorkOrderService.remove(wrapper);
                boolean deleteResult = emsWorkOrderDetailService.remove(queryWrapper);
                if (deleteResult && remove) {

                    log.info("成功删除工单号 {} 的已有工单详情数据，共删除 {} 条记录", workOrderNumber, existingDetails.size());
                    return  true;
                } else {
                    log.warn("删除工单号 {} 的已有工单详情数据失败", workOrderNumber);
                    return  false;
                }
            } else {
                log.debug("工单号 {} 在ems_work_order_detail表中没有已有数据", workOrderNumber);
                return  true;
            }
            
        } catch (Exception e) {
            log.error("清理工单号 {} 的工单详情数据时发生异常: {}", workOrderNumber, e.getMessage());
            return  false;
        }
    }
    
    /**
     * 清理当前工单号相关的Redis缓存
     * @param workOrderNumber 工单号
     */
    private void clearWorkOrderRedisCache(String workOrderNumber) {
        if (StringUtils.isBlank(workOrderNumber)) {
            return;
        }
        
        try {
            // 构建所有可能的Redis key
            String detailKey = RedisKeyEnum.WORKER_ORDER_DEATIL_PREFIX.getValue() + workOrderNumber;
            String bomKey = RedisKeyEnum.WORKER_ORDER_BOM_PREFIX.getValue() + workOrderNumber;
            String approvalKey = RedisKeyEnum.WORKER_ORDER_APPROVAL_PREFIX.getValue() + workOrderNumber;
            String newKey = RedisKeyEnum.WORKER_ORDER_NEW_PREFIX.getValue() + workOrderNumber;
            
            // 检查并删除存在的key
            if (redisTemplate.hasKey(detailKey)) {
                redisTemplate.delete(detailKey);
                log.info("删除Redis缓存: {}", detailKey);
            }
            
            if (redisTemplate.hasKey(bomKey)) {
                redisTemplate.delete(bomKey);
                log.info("删除Redis缓存: {}", bomKey);
            }
            
            if (redisTemplate.hasKey(approvalKey)) {
                redisTemplate.delete(approvalKey);
                log.info("删除Redis缓存: {}", approvalKey);
            }
            
            if (redisTemplate.hasKey(newKey)) {
                redisTemplate.delete(newKey);
                log.info("删除Redis缓存: {}", newKey);
            }
            
            log.info("工单号 {} 相关的Redis缓存清理完成", workOrderNumber);
            
        } catch (Exception e) {
            log.error("清理工单号 {} 的Redis缓存时发生异常: {}", workOrderNumber, e.getMessage());
            // 不抛出异常，避免影响主要业务逻辑
        }
    }
}






